# 工具链配置
RISCV_PREFIX = riscv64-unknown-elf-
CC = $(RISCV_PREFIX)gcc
LD = $(RISCV_PREFIX)ld
AS = $(RISCV_PREFIX)as
OBJCOPY = $(RISCV_PREFIX)objcopy
OBJDUMP = $(RISCV_PREFIX)objdump

# 核目录
K = kernel

# 编译选项
CFLAGS = -Wall -Werror -Wno-unknown-attributes -O -fno-omit-frame-pointer -ggdb -gdwarf-2 # 基础编译选项
CFLAGS += -MD # 依赖关系生成
CFLAGS += -mcmodel=medany # RISC-V 特定架构选项
CFLAGS += -ffreestanding # 独立环境配置
CFLAGS += -fno-common -nostdlib# 严格控制全局变量的定义,不链接标准 C 库和启动文件
# 内置函数控制（防止编译器优化替换）
CFLAGS += -fno-builtin-strncpy -fno-builtin-strncmp -fno-builtin-strlen -fno-builtin-memset
CFLAGS += -fno-builtin-memmove -fno-builtin-memcmp -fno-builtin-log -fno-builtin-bzero
CFLAGS += -fno-builtin-strchr -fno-builtin-exit -fno-builtin-malloc -fno-builtin-putc
CFLAGS += -fno-builtin-free
CFLAGS += -fno-builtin-memcpy -Wno-main
CFLAGS += -fno-builtin-printf -fno-builtin-fprintf -fno-builtin-vprintf
CFLAGS += -I.# 头文件搜索路径
CFLAGS += $(shell $(CC) -fno-stack-protector -E -x c /dev/null >/dev/null 2>&1 && echo -fno-stack-protector)# 栈保护检测（条件性添加）

# 汇编选项
ASFLAGS = -gdwarf-2 #指示汇编器生成 ​​DWARF 版本 2​​ 格式的调试信息。

# 链接选项
LDFLAGS = -z max-page-size=4096

# 目标文件 
OBJS = \
$(K)/trap/entry.o \
$(K)/trap/start.o \
$(K)/trap/trap.o \
$(K)/trap/kernelvec.o \
$(K)/trap/trap_test.o \
$(K)/fs/main.o \
$(K)/fs/uart.o \
$(K)/fs/ansi_escapes.o \
$(K)/fs/printf.o \
$(K)/fs/printf_test.o \
$(K)/fs/sprintf.o \
$(K)/fs/console.o \
$(K)/mm/kalloc.o \
$(K)/mm/vm.o \
$(K)/mm/mm_test.o

# 依赖文件列表
DEPS = $(OBJS:.o=.d)

# 编译规则
$(K)/%.o: $(K)/%.S
	$(CC) -c $(CFLAGS) $(ASFLAGS) -o $@ $<

$(K)/%.o: $(K)/%.c
	$(CC) -c $(CFLAGS) -o $@ $<

# 内核目标文件构建规则
$(K)/kernel.elf: $(OBJS) $(K)/kernel.ld
	@echo "Linking kernel..."
	$(LD) $(LDFLAGS) -T $(K)/kernel.ld -o $@ $(OBJS)
	$(OBJDUMP) -S $@ > $(K)/kernel.asm
	$(OBJDUMP) -t $@ | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > $(K)/kernel.sym

# 标签文件生成规则
tags: $(OBJS)
	etags $(K)/*.S $(K)/*.c

# 最终镜像
TARGET = kernel.elf

# 默认目标
all: $(TARGET)

# 生成二进制镜像
$(TARGET): $(K)/kernel.elf
	$(OBJCOPY) -O binary $< $@
	$(OBJDUMP) -S $< > $(K)/kernel.asm  # 生成反汇编便于调试

# 清理生成文件
clean:
	rm -f *.o kernel/*.o kernel.elf kernel.asm kernel.sym
	rm -f kernel/*.d kernel/*/*.o kernel/*/*.d

# 运行（需要QEMU支持）
qemu: $(TARGET)
	qemu-system-riscv64 -machine virt -bios none -kernel $(TARGET) -m 128M -smp 1 -nographic

# 调试（QEMU + GDB）
debug: $(TARGET)
	qemu-system-riscv64 -machine virt -bios none -kernel $(TARGET) -m 128M -smp 1 -nographic -s -S &
	$(RISCV_PREFIX)gdb -ex "target remote localhost:1234" $(K)/kernel.elf

.PHONY: all clean qemu debug

